package editor.logic;

import blazingbubble.config.Config;
import editor.graphics.Window;
import moltencore.game.loader.LevelSprite;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import spark.exception.LoadingException;
import spark.graphics.SpriteMap;
import spark.graphics.SpriteMapParser;
import spark.graphics.SpriteRenderable;
import spark.math.Vector2;
import spark.math.Vector3;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

public class LevelParser2 extends moltencore.game.loader.LevelParser {
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		if(localName.equals(moltencore.game.loader.LevelParser.ELEMENT_LEVEL_SPRITE)) {
			try {
				spriteMapStuff(attributes, Config.getResourcePath() + Window.DEFAULT_THEME_PATH);
			}
			catch(LoadingException e) {
				throw new SAXException(e);
			}

			LevelSprite sprite = new LevelSprite(new SpriteRenderable(),
			                                     attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_SPRITE_MAP),
			                                     attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_THEME),
			                                     attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_ID));
			try {
				sprite.getRenderable().setPosition(new Vector3(
						Float.parseFloat(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_POS_X)),
						Float.parseFloat(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_POS_Y)),
						Float.parseFloat(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_POS_Z))));
				sprite.getRenderable().setDimensions(new Vector2(
						Float.parseFloat(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_SCALE_X)),
						Float.parseFloat(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_SCALE_Y))));
			}
			catch(NumberFormatException e) {
				throw new SAXException(e);
			}
			level.addSprite(sprite);
		}
	}

	private void spriteMapStuff(Attributes attributes, String themePath) throws LoadingException {
		HashMap<String, SpriteMap.SpriteData> spriteDataMap = new HashMap<String, SpriteMap.SpriteData>();
		File[] themeFile = new File[1];
		File spriteMap = new File(Config.getResourcePath() + Window.SPRITE_MAP_PATH + "/" + attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_SPRITE_MAP));
		if(!LevelSpriteFactory.levelSpriteFactoryHandler.containsFactory(attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_SPRITE_MAP) + ":" + attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_THEME))) {
			getSpriteMapData(
					spriteMap,
					themePath,
					attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_THEME),
					spriteDataMap, themeFile);
			String[] mapNamePieces = spriteMap.getAbsolutePath().split("[/\\\\\\\\]");
			new LevelSpriteFactory(mapNamePieces[mapNamePieces.length - 1], themePath, attributes.getValue(moltencore.game.loader.LevelParser.ATTRIBUTE_THEME), spriteDataMap);
		}
	}

	private void getSpriteMapData(File spriteMap, String themePath, String theme, HashMap<String, SpriteMap.SpriteData> spriteDataMap, File[] themeFile) throws LoadingException {
		try {
			XMLReader reader = XMLReaderFactory.createXMLReader();
			SpriteMapParser parser = new SpriteMapParser(theme, spriteDataMap);
			reader.setContentHandler(parser);
			reader.parse(spriteMap.getAbsolutePath());
			themeFile[0] = new File(themePath + parser.getThemeFileName());
			if(!themeFile[0].exists()) {
				throw new LoadingException("Theme file of theme " + theme + "(" + themeFile[0].getAbsolutePath() + ") does not exist");
			}
		}
		catch(SAXException e) {
			throw new LoadingException(e);
		}
		catch(IOException e) {
			throw new LoadingException(e);
		}
	}
}
